const express = require('express');
const mysql = require('mysql2');
const bodyParser = require('body-parser');
const cors = require('cors');

const app = express();
const port = 3001;

const pool = mysql.createPool({
  host: 'localhost',
  user: 'root',
  password: '123456',
  database: 'nft'
});

app.use(bodyParser.json());
app.use(cors());


//保存NFT
app.post('/saveNFT', (req, res) => {
  let { tokenId, category, address, cid, description, status, leaseStatus, price } = req.body;
  console.log('收到请求:', req.body);  // 打印请求的 body 数据

  // 给 status 和 leaseStatus 设置默认值，如果它们为空或未定义
  status = status || '未上架';  // 默认值为 '未上架'
  leaseStatus = leaseStatus || '未租赁';  // 默认值为 '未租赁'

  const query = `
    INSERT INTO nfts (tokenId, category, address, cid, description, status, leaseStatus, price) 
    VALUES (?, ?, ?, ?, ?, ?, ?, ?)
  `;

  pool.execute(query, [tokenId, category, address, cid, description, status, leaseStatus, price], (err, result) => {
    if (err) {
      console.error('Failed to save NFT:', err);
      return res.status(500).json({ error: 'Failed to save NFT' });
    }
    res.status(200).json({ message: 'NFT saved successfully', nftId: result.insertId });
  });
});


//保存购买记录
app.post('/purchaseRecord', (req, res) => {
  const { ownerAddress, buyerAddress, transactionHash, purchasePrice, tokenId } = req.body;

  console.log('收到购买记录请求:', req.body);  // 打印请求的 body 数据

  // 可选：价格字段验证（如果提供了购买价格，则验证）
  let price = null;
  if (purchasePrice !== undefined) {
    price = parseFloat(purchasePrice);
    if (isNaN(price) || price <= 0) {
      return res.status(400).json({ message: '无效的购买价格' });
    }
  }

  // 可选：如果提供了 ownerAddress，则进行验证
  if (ownerAddress !== undefined && (typeof ownerAddress !== 'string' || ownerAddress.trim().length === 0)) {
    return res.status(400).json({ message: '无效的 ownerAddress' });
  }

  // 可选：如果提供了 buyerAddress，则进行验证
  if (buyerAddress !== undefined && (typeof buyerAddress !== 'string' || buyerAddress.trim().length === 0)) {
    return res.status(400).json({ message: '无效的 buyerAddress' });
  }

  // 可选：如果提供了 transactionHash，则进行验证
  if (transactionHash !== undefined && (typeof transactionHash !== 'string' || transactionHash.trim().length === 0)) {
    return res.status(400).json({ message: '无效的 transactionHash' });
  }

  // 不再验证 tokenId，直接使用传入的值

  // 创建 SQL 插入语句
  const query = `
    INSERT INTO purchase_records (owner_address, buyer_address, transaction_hash, purchase_price, tokenId)
    VALUES (?, ?, ?, ?, ?)
  `;

  // 如果某些字段为 undefined，则将其设置为 NULL，避免插入无效数据
  const values = [
    ownerAddress || null,
    buyerAddress || null,
    transactionHash || null,
    price !== null ? price : null,  // 价格字段如果没有提供，则设置为 NULL
    tokenId || null  // tokenId 如果没有提供，则设置为 NULL
  ];

  // 执行插入操作
  pool.execute(query, values, (err, result) => {
    if (err) {
      console.error('插入购买记录失败:', err);
      return res.status(500).json({ error: '插入购买记录失败' });
    }
    res.status(200).json({ message: '购买记录保存成功', recordId: result.insertId });
  });
});




// 查询购买记录（根据 NFT 的ID查询）
app.get('/purchaseRecord/:tokenId', (req, res) => {
  const { tokenId } = req.params;  // 获取路由中的 tokenId 参数

  // 确保 tokenId 参数存在并且有效
  if (!tokenId || isNaN(tokenId)) {
    return res.status(400).json({ message: '无效的 tokenId 参数' });  // 如果没有传入有效的 tokenId，返回 400 错误
  }

  // 修改查询，确保是基于 tokenId 查询购买记录
  const query = 'SELECT * FROM purchase_records WHERE tokenId = ? ORDER BY purchase_date DESC';

  // 使用连接池执行查询
  pool.query(query, [tokenId], (err, results) => {
    if (err) {
      console.error('查询购买记录时发生错误:', err);  // 错误日志打印
      return res.status(500).json({ message: '查询购买记录失败' });  // 返回错误信息
    }

    // 如果没有找到结果，返回 404
    if (results.length === 0) {
      return res.status(404).json({ message: `未找到 tokenId 为 ${tokenId} 的购买记录` });
    }

    // 返回查询结果
    res.status(200).json({
      message: '购买记录查询成功',
      data: results  // 返回查询到的购买记录
    });
    console.log('购买记录查询成功:', results);  // 打印查询结果
  });
});




// 保存竞拍
app.post('/saveAuction', (req, res) => {
  const { tokenId, name, image, cid,description, startingPrice, auctionDuration, owner_address } = req.body;

  // SQL 查询
  const query = 'INSERT INTO auctions (tokenId, name, image, cid,description, startingPrice, auctionDuration, owner_address) VALUES (?, ?, ?, ?, ?, ?, ?,?)';
// console.log(query);
  // 执行数据库操作
  pool.execute(query, [tokenId, name, image, cid, description,startingPrice, auctionDuration, owner_address], (err, result) => {
    if (err) {
      // 记录错误详细信息
      console.error('Failed to save auction:', err.message);

      // 可以选择返回具体的错误信息，方便调试
      return res.status(500).json({
        error: 'Failed to save auction',
        details: err.message,  // 返回具体错误信息
      });
    }

    // 返回成功响应，并包含插入的 `auctionId`
    res.status(200).json({
      message: 'Auction saved successfully',
      auctionId: result.insertId,
    });
  });
});




// 查询所有拍卖信息
app.get('/getAuctions', (req, res) => {
  // SQL 查询所有拍卖记录
  const query = 'SELECT * FROM auctions';

  // 执行数据库查询
  pool.execute(query, [], (err, result) => {
    if (err) {
      console.error('Failed to query auctions:', err.message);
      return res.status(500).json({
        error: 'Failed to query auctions',
        details: err.message,  // 返回具体错误信息
      });
    }

    // 如果没有找到拍卖记录
    if (result.length === 0) {
      return res.status(404).json({
        message: 'No auctions found',
      });
    }

    // 返回查询结果
    res.status(200).json({
      message: 'Auctions retrieved successfully',
      auctions: result,  // 返回所有拍卖记录
    });
  });
});





// 删除指定 tokenId 的 正在拍卖的NFT 数据
app.delete('/deleteNFT/:tokenId', (req, res) => {
  const { tokenId } = req.params;  // 获取路由参数中的 tokenId

  // 检查 tokenId 是否存在
  if (!tokenId) {
    return res.status(400).json({
      error: 'Missing tokenId parameter',
    });
  }

  // 构建 SQL 查询来删除对应的 NFT 数据
  const query = 'DELETE FROM auctions WHERE tokenId = ?';

  // 执行删除操作
  pool.execute(query, [tokenId], (err, result) => {
    if (err) {
      console.error('Failed to delete NFT:', err.message);
      return res.status(500).json({
        error: 'Failed to delete NFT',
        details: err.message,  // 返回具体的错误信息
      });
    }

    // 如果没有找到对应的 NFT
    if (result.affectedRows === 0) {
      return res.status(404).json({
        message: 'NFT not found',
      });
    }

    // 成功删除NFT数据
    res.status(200).json({
      message: `NFT with tokenId ${tokenId} deleted successfully`,
    });
  });
});










//批量制作NFT
app.post('/batchNft', (req, res) => {
  const { toAddress, uris } = req.body;
  const newNfts = uris.map((uri, index) => ({
      tokenId: index + 1, 
      toAddress,
      uri,
  }));
  const sql = 'INSERT INTO batchnfts (tokenId, toaddress, uri) VALUES ?';
  const values = newNfts.map(nft => [nft.tokenId, nft.toAddress, nft.uri]);
  pool.query(sql, [values], (error, results) => {
      if (error) {
          console.error('插入 NFT 失败:', error);
          return res.status(500).json({ error: '插入 NFT 失败' });
      }
      res.status(201).json(newNfts);
  });
});

//批量获取NFT
app.get('/batchNft', (req, res) => {
  const query = 'SELECT tokenId, toaddress, uri FROM batchnfts';
  pool.query(query, (error, results) => {
      if (error) {
          console.error('获取 NFT 列表失败:', error);
          return res.status(500).json({ error: '获取 NFT 列表失败' });
      }
      res.json(results);
  });
});

//销毁NFT
app.delete('/batchNft/:tokenId', (req, res) => {
  const tokenId = req.params.tokenId; 
  const query = 'DELETE FROM batchnfts WHERE tokenId = ?';
  pool.query(query, [tokenId], (error, results) => {
    if (error) {
      console.error('删除 NFT 失败:', error);
      return res.status(500).json({ error: '删除 NFT 失败' });
    }
    if (results.affectedRows === 0) {
      return res.status(404).json({ message: '未找到对应的 NFT' });
    }
    res.status(200).json({ message: 'NFT 删除成功' });
  });
});

//删除NFT
app.delete('/batchNft/:tokenId', (req, res) => {
  const tokenId = req.params.tokenId; 
  const query = 'DELETE FROM nfts WHERE tokenId = ?';
  pool.query(query, [tokenId], (error, results) => {
    if (error) {
      console.error('删除 NFT 失败:', error);
      return res.status(500).json({ error: '删除 NFT 失败' });
    }
    if (results.affectedRows === 0) {
      return res.status(404).json({ message: '未找到对应的 NFT' });
    }
    res.status(200).json({ message: 'NFT 删除成功' });
  });
});


//收藏NFT
app.post('/favorites', (req, res) => {
  const { tokenId, cid, category, address, price } = req.body;
  const query = 'INSERT INTO favorites (tokenId, cid, category, address, price) VALUES (?, ?, ?, ?, ?)';
  pool.query(query, [tokenId, cid, category, address, price], (error, results) => {
    if (error) {
      console.error('添加收藏失败:', error);
      return res.status(500).json({ error: '添加收藏失败' });
    }
    res.status(200).json({ message: '收藏成功' });
  });
});

//取消收藏
app.delete('/favorites/:tokenId', (req, res) => {
  const { tokenId } = req.params; 

  const query = 'DELETE FROM favorites WHERE tokenId = ?';
  pool.query(query, [tokenId], (error, results) => {
    if (error) {
      console.error('取消收藏失败:', error);
      return res.status(500).json({ error: '取消收藏失败' });
    }
    if (results.affectedRows === 0) {
      return res.status(404).json({ message: '未找到对应的收藏' });
    }
    res.status(200).json({ message: '取消收藏成功' });
  });
});

//展示收藏
app.get('/favorites', (req, res) => {
  const query = 'SELECT * FROM favorites'; 
  pool.query(query, (error, results) => {
    if (error) {
      console.error('获取收藏失败:', error);
      return res.status(500).json({ error: '获取收藏失败' });
    }
    res.status(200).json(results);  
  });
});



//赠送NFT
app.put('/updateNFTAddress', (req, res) => {
  const { tokenId, newAddress } = req.body;
  if (!tokenId || !newAddress) {
    return res.status(400).json({ error: '缺少 tokenId 或新地址' });
  }
  const query = 'UPDATE nfts SET address = ? WHERE tokenId = ?';
  pool.execute(query, [newAddress, tokenId], (err, result) => {
    if (err) {
      console.error('更新地址失败:', err);
      return res.status(500).json({ error: '更新地址失败' });
    }
    if (result.affectedRows === 0) {
      return res.status(404).json({ error: '未找到指定的 tokenId' });
    }
    res.status(200).json({ message: '地址更新成功' });
  });
});


//获取当前账户的NFT
app.get('/getNFTs/:address', (req, res) => {
  const address = req.params.address;
  const query = 'SELECT * FROM nfts WHERE address = ?';
  pool.query(query, [address], (err, results) => {
    if (err) {
      console.error('获取 NFT 信息失败:', err);
      return res.status(500).json({ message: '服务器错误' });
    }
    res.status(200).json(results);
  });
});

//更新NFT上架状态
app.post('/updateNFTStatus', (req, res) => {
  const { tokenId, price, rarity } = req.body; 
  const status = '上架'; 
  const query = 'UPDATE nfts SET status = ?, price = ?, rarity = ? WHERE tokenId = ?'; 
  pool.execute(query, [status, price, rarity, tokenId], (err, result) => {
    if (err) {
      console.error('Failed to update NFT status:', err);
      return res.status(500).json({ error: 'Failed to update NFT status' });
    }
    if (result.affectedRows === 0) {
      return res.status(404).json({ message: 'NFT not found' });
    }
    res.status(200).json({ message: 'NFT status updated successfully' });
  });
});

//更新NFT租赁状态
app.post('/updateNFTleaseStatus', (req, res) => {
  const { tokenId } = req.body; 
  const leaseStatus = '租赁'; 
  const query = 'UPDATE nfts SET leaseStatus = ? WHERE tokenId = ?'; 
  pool.execute(query, [leaseStatus, tokenId], (err, result) => {
    if (err) {
      console.error('Failed to update NFT leaseStatus:', err);
      return res.status(500).json({ error: 'Failed to update NFT leaseStatus' });
    }
    if (result.affectedRows === 0) {
      return res.status(404).json({ message: 'NFT not found' });
    }
    res.status(200).json({ message: 'NFT leaseStatus updated successfully' });
  });
});

//更新购买状态
app.put('/updateNFTBuyStatus', (req, res) => {
  const { tokenId } = req.body; 
  const purchaseStatus = '已购买'; 
  const query = 'UPDATE nfts SET purchaseStatus = ? WHERE tokenId = ?'; 
  pool.execute(query, [purchaseStatus, tokenId], (err, result) => {
    if (err) {
      console.error('Failed to update NFT purchaseStatus:', err);
      return res.status(500).json
  }
  if (result.affectedRows === 0) {
    return res.status(404).json({ message: 'NFT not found' });
  }
  res.status(200).json({ message: 'NFT purchaseStatus updated successfully' });
});
});

// 获取当前已购买的 NFT
app.get('/nfts/purchased', async (req, res) => {
  const { address } = req.query;
  if (!address) {
    return res.status(400).json({ message: '缺少地址参数' });
  }
  const query = 'SELECT * FROM nfts WHERE purchaseStatus = "已购买" AND address = ?';
  pool.query(query, [address], (err, results) => {
    if (err) {
      console.error('获取已购买 NFT 信息失败:', err);
      return res.status(500).json({ message: '服务器错误' });
    }
    res.status(200).json(results);
  });
});


//获取已上架NFT
app.get('/nfts/listed', async (req, res) => {
  // const query = 'SELECT * FROM nfts WHERE status = "上架"';
  const query = 'SELECT * FROM nfts WHERE status = "上架" AND purchaseStatus = "未购买"';
  pool.query(query, (err, results) => {
    if (err) {
      console.error('获取 NFT 信息失败:', err);
      return res.status(500).json({ message: '服务器错误' });
    }
    res.status(200).json(results);
  });
});



//获取竞拍表
app.get('/getAuctions', (req, res) => {
  const query = 'SELECT * FROM auction';
  pool.execute(query, (err, results) => {
    if (err) {
      console.error('Failed to fetch auctions:', err);
      return res.status(500).json({ error: 'Failed to fetch auctions' });
    }
    res.status(200).json({ auctions: results });
  });
});

//租赁表
app.post('/saveRental', (req, res) => {
  const { tokenId, category, address, cid, rentPrice, duration } = req.body;
  const query = 'INSERT INTO rental (tokenId, category, address, cid, rentPrice, duration) VALUES (?, ?, ?, ?, ?, ?)';
  
  pool.execute(query, [tokenId, category, address, cid, rentPrice, duration], (err, result) => {
    if (err) {
      console.error('Failed to save rental:', err);
      return res.status(500).json({ error: 'Failed to save rental' });
    }
    res.status(200).json({ message: 'Rental saved successfully', rentalId: result.insertId });
  });
});

//获取租赁表
app.get('/getRental', (req, res) => {
  const query = 'SELECT * FROM rental';
  pool.execute(query, (err, results) => {
    if (err) {
      console.error('Failed to fetch rental:', err);
      return res.status(500).json({ error: 'Failed to fetch rental' });
    }
    res.status(200).json({ rentals: results }); 
  });
});

//碎片化表
app.post('/saveFractionalData', (req, res) => {
  const { tokenId, slicesCID, address } = req.body;
  const values = slicesCID.map((cid, index) => [tokenId, `NFT_${tokenId}_slice_${index + 1}`, cid, address]);
  const sql = 'INSERT INTO fractional (tokenId, sliceName, cid, address) VALUES ?';
  pool.query(sql, [values], (error, results) => {
    if (error) {
      console.error('保存到数据库失败:', error);
      return res.status(500).send('数据库保存失败');
    }
    res.send('数据成功保存到数据库');
  });
});

//获取碎片化表
app.get('/getFractionalData', (req, res) => {
  const address = req.query.address;
  if (!address) {
    return res.status(400).json({ error: '地址是必需的' });
  }
  const sql = 'SELECT * FROM fractional WHERE address = ?';
  pool.query(sql, [address], (error, results) => {
    if (error) {
      console.error('查询数据库失败:', error);
      return res.status(500).json({ error: '数据库查询失败' });
    }
    res.json(results);
  });
});

app.post('/updateaddress', (req, res) => {
  const { tokenId, cid, newAddress } = req.body;
  if (!tokenId || !cid || !newAddress) {
      return res.status(400).json({ error: 'tokenId、cid和新地址是必需的' });
  }
  const sql = 'UPDATE fractional SET address = ? WHERE tokenId = ? AND cid = ?';
  pool.query(sql, [newAddress, tokenId, cid], (error, results) => {
      if (error) {
          console.error('更新数据库失败:', error);
          return res.status(500).json({ error: '更新失败' });
      }
      if (results.affectedRows === 0) {
          return res.status(404).json({ error: '未找到相应的NFT' });
      }
      res.status(200).json({ message: 'NFT账户地址更新成功' });
  });
});





app.listen(port, () => {
  console.log(`服务器运行在端口 ${port}`);
});
